package com.rightsidetech.activity.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.activity.dto.request.ActOrderNumReq;
import com.rightsidetech.activity.dto.request.gift.*;
import com.rightsidetech.activity.dto.response.gift.*;
import com.rightsidetech.activity.entity.*;
import com.rightsidetech.activity.mapper.*;
import com.rightsidetech.activity.service.ActGiftService;
import com.rightsidetech.commom.base.DelReq;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.ActivityName;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.exception.BizException;
import com.rightsidetech.commom.utils.BeanValidator;
import com.rightsidetech.commom.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("actGiftService")
public class ActGiftServiceImpl implements ActGiftService {

    @Resource
    private ActGiftActivityMapper actGiftActivityMapper;
    @Resource
    private ActGiftActivityStoreMapper actGiftActivityStoreMapper;
    @Resource
    private ActActivityMallTypeMapper actActivityMallTypeMapper;
    @Resource
    private ActActivityMallTypeGiftMapper actActivityMallTypeGiftMapper;
    @Resource
    private ActActivityNumMapper actActivityNumMapper;
    @Resource
    private ActActivityAuditRecordMapper actActivityAuditRecordMapper;
    @Resource
    private ActActivityRelationMapper actActivityRelationMapper;
    @Resource
    private ActGiftRecordMapper actGiftRecordMapper;
    @Resource
    private ActGiftActivityStatisMapper actGiftActivityStatisMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData saveActGift(ActGiftSaveReq req, String createrName, Long createrId,List<Long> oldStoreIds) throws Exception {
        ResponseData check = checkReq(req);
        if(check != null){
            return check;
        }
        if (actGiftActivityMapper.selectCountByName(req.getEventName()) > 0) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"活动名称已存在");
        }
        ActGiftActivity record = new ActGiftActivity();
        record.setEventName(req.getEventName());
        record.setStartTime(req.getStartTime());
        String date1 = DateUtil.getDate(req.getEndTime(), "yyyy-MM-dd 23:59:59");
        record.setEndTime(DateUtil.getDate(date1,"yyyy-MM-dd HH:mm:ss"));
        Date date = new Date();
        record.setCreatedAt(date);
        record.setCreaterName(createrName);
        record.setCreaterId(createrId);
//        List<Integer> numList = req.getGiftMallType().stream().map(ActGiftNumberReq::getNum).collect(Collectors.toList());
        Integer totalNum = 0;
//        for (Integer num : numList) {
//            totalNum += num;
//        }
        List<ActGiftMallTypeReq> giftMallType = req.getGiftMallType();
        for (ActGiftMallTypeReq actGiftMallTypeReq : giftMallType) {
            List<ActGiftMallTypeIdAndNumbersReq> giftCommodityIds = actGiftMallTypeReq.getGiftCommodityIds();
            for (ActGiftMallTypeIdAndNumbersReq giftCommodityId : giftCommodityIds) {
                totalNum += giftCommodityId.getNum();
            }
        }
        record.setTotalNum(totalNum);
        if (actGiftActivityMapper.insertSelective(record) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
        //保存活动与门店/代理商/大区 关联
        ActActivityRelationWithBLOBs relation = new ActActivityRelationWithBLOBs();
        relation.setType((byte) 0);
        relation.setRelationId(record.getId());
        relation.setCreatedAt(new Date());
        relation.setAreaIdArray(req.getAreaIds().toString());
        relation.setAgentIdArray(req.getAgentIds().toString());
        relation.setStoreIdArray(oldStoreIds.toString());
        actActivityRelationMapper.insertSelective(relation);

        saveGiftFrom(req, record, date,req.getStoreIds());
        return ResponseData.success(CodeIdEnum.Success);
    }

    private void saveGiftFrom(ActGiftSaveReq req, ActGiftActivity record, Date date,List<Long> storeIds) throws BizException {
        Map<String,Object> map = new HashMap<>();
        map.put("giftActivityId",record.getId());
        map.put("list",storeIds);
        if (actGiftActivityStoreMapper.insertList(map) <= 0){
            throw new BizException(CodeIdEnum.FAILED);
        }
        List<ActGiftMallTypeReq> giftMallType = req.getGiftMallType();
        for (ActGiftMallTypeReq mallTypeReq : giftMallType) {
            ActActivityMallType mallType = new ActActivityMallType();
            mallType.setGiftActivityId(record.getId());
            mallType.setMallTypeId(mallTypeReq.getMallTypeId());
            mallType.setMallTypeName(mallTypeReq.getMallTypeName());
            mallType.setCreatedAt(date);
            if (actActivityMallTypeMapper.insertSelective(mallType) <= 0) {
                throw new BizException(CodeIdEnum.FAILED);
            }
//            List<Long> commodityIds = mallTypeReq.getGiftCommodityIds();
            List<ActGiftMallTypeIdAndNumbersReq> giftCommodityIds = mallTypeReq.getGiftCommodityIds();

            map.put("activityMallTypeId",mallType.getId());
            map.put("list",giftCommodityIds);
            if (actActivityMallTypeGiftMapper.insertList(map) <= 0) {
                throw new BizException(CodeIdEnum.FAILED);
            }
        }
       /* for (ActGiftMallTypeReq actGiftMallTypeReq : req.getGiftMallType()) {
            for (ActGiftMallTypeIdAndNumbersReq giftCommodityId : actGiftMallTypeReq.getGiftCommodityIds()) {
                map.put("list",giftCommodityId.getNum());
            }
        }*/

//        map.put("list",req.getGiftNum());
        if (actActivityNumMapper.insertList(map) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
    }

    private ResponseData checkReq(ActGiftSaveReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        Date date = getYesterDay();
        Date startTime = req.getStartTime();
        Date endTime = req.getEndTime();
        if(startTime.compareTo(date) < 0){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"活动开始时间不可小于当日凌晨");
        }
        if(startTime.compareTo(endTime) > 0){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"活动开始时间不可大于结束时间");
        }
        if (new HashSet<>(req.getStoreIds()).size() < req.getStoreIds().size()) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"门店id不可重复");
        }
        List<ActGiftMallTypeReq> giftMallType = req.getGiftMallType();
//        List<ActGiftNumberReq> giftNum = req.getGiftNum();
        for (ActGiftMallTypeReq mallTypeReq : giftMallType) {
            if (new HashSet<>(mallTypeReq.getGiftCommodityIds()).size() < mallTypeReq.getGiftCommodityIds().size()) {
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"商城分类id不可重复");
            }
            ConstraintViolation validate1 = BeanValidator.validate(mallTypeReq);
            if (validate1 != null) {
                return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate1.getMessage());
            }
        }
     /*   if (giftNum.stream().map(ActGiftNumberReq::getGiftCommodityId).collect(Collectors.toSet()).size() < giftNum.size()) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"商城分类id不可重复");
        }*/
       /* for (ActGiftNumberReq giftNumberReq : giftNum) {
            ConstraintViolation validate2 = BeanValidator.validate(giftNumberReq);
            if (validate2 != null) {
                return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate2.getMessage());
            }
        }*/
        return null;
    }

    @Override
    public ResponseData<PageInfo<ActGiftPageResp>> page(ActGiftPageReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActGiftPageResp> result = actGiftActivityMapper.selectPageList(req);
        return ResponseData.success(new PageInfo<>(result));
    }

    @Override
    public List<ActGiftActivityStore> selectActStoreByGiftId(Long giftId) {
        return actGiftActivityStoreMapper.selectListByGiftId(giftId);
    }

    @Override
    public ResponseData<ActGiftDetailResp> details(Long id) {
        if(null == id || id < 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "id不可为空或小于1");
        }
        ActGiftActivity activity = actGiftActivityMapper.selectByPrimaryKey(id);
        if(ObjectUtil.isEmpty(activity) || activity.getIsDeleted() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "未找到查找数据");
        }
        ActGiftDetailResp resp = new ActGiftDetailResp();
        resp.setId(activity.getId());
        resp.setEventName(activity.getEventName());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        resp.setStartTime(format.format(activity.getStartTime()));
        resp.setEndTime(format.format(activity.getEndTime()));
        List<ActGiftDetailTypeResp> giftMallType = actActivityMallTypeMapper.selectGiftActivityId(activity.getId());
        for (ActGiftDetailTypeResp typeResp : giftMallType) {
            List<ActGiftDetailComResp> list = actActivityMallTypeGiftMapper.selectByActivityMallTypeId(typeResp.getId());
            typeResp.setGiftCommodityIds(list);
        }
        resp.setGiftMallType(giftMallType);
        List<ActGiftNumResp> giftNum = actActivityNumMapper.selectByGiftActivityId(activity.getId());
//        resp.setGiftNum(giftNum);
        ActActivityRelationWithBLOBs relation = actActivityRelationMapper.selectByActId(id,(byte)0);
        if (!ObjectUtils.isEmpty(relation)){
            resp.setAreaIdArray(relation.getAreaIdArray());
            resp.setAgentIdArray(relation.getAgentIdArray());
            resp.setStoreIdArray(relation.getStoreIdArray());
        }
        return ResponseData.success(resp);
    }

    @Override
    public ResponseData arraignmentAct(DelReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        ActGiftActivity activity = actGiftActivityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(activity) || activity.getIsDeleted() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "未找到提审的活动");
        }
        if(activity.getStatus() != 0){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "活动状态不正确");
        }
        activity = new ActGiftActivity();
        activity.setId(req.getId());
        activity.setStatus((byte) 1);
        if (actGiftActivityMapper.updateByPrimaryKeySelective(activity) <= 0) {
            return ResponseData.fail("操作失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData verifyAct(ActVerifyReq req,String createrName,Long createrId) throws Exception {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        ActGiftActivity activity = actGiftActivityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(activity) || activity.getIsDeleted() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "未找到需要审核的活动");
        }
        if(activity.getStatus() != 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "活动状态不正确");
        }
        ActActivityAuditRecord record = new ActActivityAuditRecord();
        record.setAuditContent(req.getAuditContent());
        record.setCreatedName(createrName);
        record.setCreatedAt(new Date());
        record.setCreaterId(createrId);
        record.setActivityName(ActivityName.GIFT_ACTIVITY.getActivityName());
        record.setEventName(activity.getEventName());
        record.setActivityId(activity.getId());
        if(req.getStatus() == 1){
            if(StrUtil.isBlank(req.getAuditContent())){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "驳回活动驳回理由不可为空");
            }
            record.setAuditStatus((byte)-1);
            if (actActivityAuditRecordMapper.insertSelective(record) <= 0) {
                throw new BizException(CodeIdEnum.FAILED);
            }
            activity = new ActGiftActivity();
            activity.setId(req.getId());
            activity.setStatus((byte)-1);
            if (actGiftActivityMapper.updateByPrimaryKeySelective(activity) <= 0) {
                throw new BizException(CodeIdEnum.FAILED);
            }
            return ResponseData.success(CodeIdEnum.Success);
        }
        record.setAuditStatus((byte)1);
        if (actActivityAuditRecordMapper.insertSelective(record) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
        activity = new ActGiftActivity();
        activity.setId(req.getId());
        activity.setStatus((byte)2);
        if (actGiftActivityMapper.updateByPrimaryKeySelective(activity) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData updateAct(ActGiftUpReq req,String updaterName,Long updaterId,List<Long> storeIds) throws Exception {
        ResponseData check = checkReq(req);
        if(ObjectUtil.isNotEmpty(check)){
            return check;
        }
        ActGiftActivity activity = actGiftActivityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(activity) || activity.getIsDeleted() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到需要修改的数据");
        }
        if(activity.getStatus() == 1 || activity.getStatus() == 3){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"审核中(已结束)的活动不允许修改");
        }
        if(activity.getStatus() == 2){
            if(activity.getStartTime().compareTo(new Date()) < 0){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"正在进行中的活动不可编辑");
            }
        }
        if(!activity.getEventName().equals(req.getEventName())){
            if (actGiftActivityMapper.selectCountByName(req.getEventName()) > 0) {
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"此活动名已存在");
            }
        }
        if (actActivityNumMapper.deleteByActivityId(activity.getId()) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
        if(actGiftActivityStoreMapper.deleteByActivityId(activity.getId()) <= 0){
            throw new BizException(CodeIdEnum.FAILED);
        }
        List<ActGiftDetailTypeResp> mallTypeList = actActivityMallTypeMapper.selectGiftActivityId(activity.getId());
        for (ActGiftDetailTypeResp typeResp : mallTypeList) {
            if (actActivityMallTypeGiftMapper.deleteByActivityMallTypeId(typeResp.getId()) <= 0) {
                throw new BizException(CodeIdEnum.FAILED);
            }
        }
        if (actActivityMallTypeMapper.deleteByActivityId(activity.getId()) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
        saveGiftFrom(req,activity,new Date(),storeIds);
        activity = new ActGiftActivity();
        activity.setId(req.getId());
        activity.setEventName(req.getEventName());
        activity.setStartTime(req.getStartTime());
        activity.setEndTime(req.getEndTime());
        activity.setStatus((byte)0);
        activity.setUpdaterId(updaterId);
        activity.setUpdaterName(updaterName);
        activity.setUpdatedAt(new Date());
        Integer totalNum = 0;
        //总数量actGiftMallTypeReq下的giftCommodityIds下的num
        for (ActGiftMallTypeReq actGiftMallTypeReq : req.getGiftMallType()) {
            List<ActGiftMallTypeIdAndNumbersReq> giftCommodityIds = actGiftMallTypeReq.getGiftCommodityIds();
            for (ActGiftMallTypeIdAndNumbersReq giftCommodityId : giftCommodityIds) {
                totalNum += giftCommodityId.getNum();
            }
        }
        activity.setTotalNum(totalNum);
        if (actGiftActivityMapper.updateByPrimaryKeySelective(activity) <= 0) {
            throw new BizException(CodeIdEnum.FAILED);
        }
        //修改活动和门店/代理商/大区 关联
        ActActivityRelationWithBLOBs relationWithBLOBs = actActivityRelationMapper.selectByActId(req.getId(),(byte)0);
        if (!ObjectUtils.isEmpty(relationWithBLOBs)){
            ActActivityRelationWithBLOBs withBLOBs = new ActActivityRelationWithBLOBs();
            withBLOBs.setId(relationWithBLOBs.getId());
            withBLOBs.setAreaIdArray(req.getAreaIds().toString());
            withBLOBs.setAgentIdArray(req.getAgentIds().toString());
            withBLOBs.setStoreIdArray(req.getStoreIds().toString());
            actActivityRelationMapper.updateByPrimaryKeySelective(withBLOBs);
        }

        return ResponseData.success(CodeIdEnum.Success);
    }


    @Override
    public ResponseData delete(DelReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        ActGiftActivity activity = actGiftActivityMapper.selectByPrimaryKey(req.getId());
        if(ObjectUtil.isEmpty(activity)|| activity.getIsDeleted() == 1){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到需要删除的数据");
        }
        if(activity.getStatus() == 2){
            if(activity.getStartTime().compareTo(new Date()) < 0){
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"正在进行中的活动不可删除");
            }
        }
        activity = new ActGiftActivity();
        activity.setId(req.getId());
        activity.setIsDeleted((byte)1);
        if (actGiftActivityMapper.updateByPrimaryKeySelective(activity) <= 0) {
            return ResponseData.fail("操作失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public List<Long> getTypeIdsByActId(Long giftActivityId) {
        List<ActGiftDetailTypeResp> resp = actActivityMallTypeMapper.selectGiftActivityId(giftActivityId);
        return resp.stream().map(ActGiftDetailTypeResp::getMallTypeId).collect(Collectors.toList());
    }

    @Override
    public List<ActGiftUserAppResp> selectGiftIdAndNum(Long typeId,Long storeId) {
        return actGiftActivityMapper.selectGiftIdAndNum(typeId,storeId);
    }

    @Override
    public boolean checkGift(Long typeId, Long giftId,Long storeId) {
        return actGiftActivityMapper.selectCountByTypeIdAndGiftId(typeId,giftId,storeId) > 0;
    }

    /**
     * 昨天 11:59:59
     * @return
     */
    private Date getYesterDay(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DAY_OF_MONTH)-1,23,59,59);
        return calendar.getTime();
    }

    @Override
    public boolean isGiftByTypeId(Long typeId,Long storeId) {
        return actGiftActivityMapper.selectCountByTypeId(typeId,storeId) > 0;
    }

    @Override
    public void updateActByOrder(List<ActOrderNumReq> list) {
        if(CollUtil.isEmpty(list)){
            return;
        }
        for (ActOrderNumReq req : list) {
            ActActivityNum actNum = actGiftActivityMapper.selectActNumId(req.getStoreId(),req.getGiftId(),req.getTypeId());
            if(ObjectUtil.isEmpty(actNum)){
                log.error("订单:{} 查询换购商品为空 换购商品id:{} 门店id: {}",req.getOrderNo(),req.getGiftId(),req.getStoreId());
                continue;
            }
            Long id = actNum.getId();
            Integer stock = actNum.getStock();
            ActActivityNum record = new ActActivityNum();
            record.setId(id);
            record.setStock(stock - req.getNum());
            actActivityNumMapper.updateByPrimaryKeySelective(record);

            ActGiftRecord actGiftRecord = new ActGiftRecord();
            actGiftRecord.setActivityId(actNum.getGiftActivityId());
            actGiftRecord.setStoreId(req.getStoreId());
            actGiftRecord.setOrderNo(req.getOrderNo());
            actGiftRecord.setGiftName(req.getGiftName());
            actGiftRecord.setGiftSpecs(req.getGiftSpecs());
            actGiftRecord.setGiftId(req.getGiftId());
            actGiftRecord.setNum(req.getNum());
            actGiftRecord.setRecordType((byte)0);
            actGiftRecord.setCreatedAt(new Date());
            actGiftRecordMapper.insertSelective(actGiftRecord);
        }
    }


    @Override
    public ResponseData<PageInfo<ActGiftCountPageResp>> countActPage(ActGiftCountPageReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActGiftCountPageResp> result = actGiftActivityStatisMapper.selectList(req);
        return ResponseData.success(new PageInfo<>(result));
    }

    @Override
    public ResponseData<List<ActGiftCountDetailResp>> countDetail(DelReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        List<ActActivityNum> list = actActivityNumMapper.selectBaseByGiftActivityId(req.getId());
        if(CollUtil.isEmpty(list)){
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(),"未找到活动");
        }
        List<ActGiftCountDetailResp> resps = new ArrayList<>();
        for (ActActivityNum num : list) {
            ActGiftCountDetailResp resp = new ActGiftCountDetailResp();
            resp.setGiftId(num.getGiftId());
            resp.setTotalNum(num.getNum());
            resp.setSurplusNum(num.getStock());
            resp.setGiftNum(num.getNum() - num.getStock());
            resps.add(resp);
        }
        return ResponseData.success(resps);
    }

    @Override
    public void updateStatus() {
        actGiftActivityMapper.updateStatus();
    }

    @Override
    public List<Integer> selectByGiftId(long id) {
        return actActivityMallTypeGiftMapper.selectByGiftId(id) ;
    }
}
